原始题目:剑指 Offer 53 - I. 在排序数组中查找数字 I (opens new window)

解题思路:

假设有一个大小为 targettarget 的数字要插入数组 numsnums,根据选择排序的思路,我们可以想到这个数组要插入到 target 的右边界的后面,记这个位置为 rightright

假设有一个大小为 x=target1x = target-1 的数字要插入数组 numsnums,根据前面的叙述,xx 应该插在数组中 x 的有边界的后面,记这个位置为 leftleft

那么 leftleftrightright 有什么关系呢?

可以得知,leftleftrightright 中间夹着的就是 targettarget 元素,rightleftright - left 就是 targettarget 出现的次数。

代码:

public int search(int[] nums, int target) {
    return helper(nums, target) - helper(nums, target - 1);
}

/**
 * 找到一个右边界,可以让 target 插入
 */
private int helper(int[] nums, int target) {
    int i = 0, j = nums.length - 1;
    while (i <= j) {
        int mid = (i + j) / 2;
        if (nums[mid] <= target) {
            i = mid + 1;
        } else {
            j = mid - 1;
        }
    }
    return i;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

复杂度分析

  • 时间复杂度O(logN)O(logN):二分法为对数级别的复杂度。
  • 空间复杂度O(1)O(1):辅助变量占用常数大小的额外空间。
上次更新: 2023/10/15